package com.campus.campusdelivery.controller;

import com.campus.campusdelivery.dto.*;
import com.campus.campusdelivery.entity.Address;
import com.campus.campusdelivery.repository.AddressRepository;
import com.campus.campusdelivery.service.OrderService;
import com.campus.campusdelivery.service.UserService;
import com.campus.campusdelivery.util.UserContextUtil;
import jakarta.validation.Valid;
import lombok.RequiredArgsConstructor;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;

import java.util.List;
import java.util.stream.Collectors;

@RestController
@RequestMapping("/api/user")
@RequiredArgsConstructor
@CrossOrigin(origins = "*")
public class UserController {
    
    private final UserService userService;
    private final OrderService orderService;
    private final UserContextUtil userContextUtil;
    private final AddressRepository addressRepository;
    
    @GetMapping("/profile")
    public ApiResponse<UserProfileDto> getUserProfile() {
        try {
            Long userId = userContextUtil.getCurrentUserId();
            UserProfileDto profile = userService.getUserProfile(userId);
            return ApiResponse.success(profile);
        } catch (Exception e) {
            return ApiResponse.error(e.getMessage());
        }
    }
    
    @PutMapping("/profile")
    public ApiResponse<Void> updateUserProfile(@Valid @RequestBody UserProfileDto profileDto) {
        try {
            Long userId = userContextUtil.getCurrentUserId();
            userService.updateUserProfile(userId, profileDto);
            return ApiResponse.success("用户信息更新成功", null);
        } catch (Exception e) {
            return ApiResponse.error(e.getMessage());
        }
    }
    
    @PostMapping("/change-password")
    public ApiResponse<Void> changePassword(@Valid @RequestBody ChangePasswordRequest request) {
        try {
            Long userId = userContextUtil.getCurrentUserId();
            userService.changePassword(userId, request);
            return ApiResponse.success("密码修改成功", null);
        } catch (Exception e) {
            return ApiResponse.error(e.getMessage());
        }
    }
    
    @DeleteMapping("/account")
    public ApiResponse<Void> deleteAccount(@RequestBody ChangePasswordRequest request) {
        try {
            Long userId = userContextUtil.getCurrentUserId();
            userService.deleteAccount(userId, request.getPassword());
            return ApiResponse.success("账号注销成功", null);
        } catch (Exception e) {
            return ApiResponse.error(e.getMessage());
        }
    }
    
    @GetMapping("/orders")
    public ApiResponse<Page<OrderDto>> getUserOrders(Pageable pageable,
                                                    @RequestParam(required = false) String status) {
        try {
            Long userId = userContextUtil.getCurrentUserId();
            Page<OrderDto> orders = orderService.getOrdersByUserId(userId, pageable, status);
            return ApiResponse.success(orders);
        } catch (Exception e) {
            return ApiResponse.error(e.getMessage());
        }
    }
    
    // 地址管理相关接口
    @GetMapping("/addresses")
    public ApiResponse<List<AddressDto>> getAddresses() {
        try {
            Long userId = userContextUtil.getCurrentUserId();
            List<Address> addresses = addressRepository.findByUserIdOrderByIsDefaultDescCreateTimeDesc(userId);
            List<AddressDto> addressDtos = addresses.stream().map(this::convertToDto).collect(Collectors.toList());
            return ApiResponse.success(addressDtos);
        } catch (Exception e) {
            return ApiResponse.error(e.getMessage());
        }
    }
    
    @PostMapping("/addresses")
    @Transactional
    public ApiResponse<Void> addAddress(@Valid @RequestBody AddressDto addressDto) {
        try {
            Long userId = userContextUtil.getCurrentUserId();
            
            // 如果设置为默认地址，先取消其他默认地址
            if (addressDto.getIsDefault()) {
                addressRepository.clearDefaultAddresses(userId);
            }
            
            Address address = new Address();
            address.setUserId(userId);
            address.setName(addressDto.getName());
            address.setPhone(addressDto.getPhone());
            address.setDetail(addressDto.getDetail());
            address.setIsDefault(addressDto.getIsDefault());
            
            addressRepository.save(address);
            return ApiResponse.success("地址添加成功", null);
        } catch (Exception e) {
            return ApiResponse.error(e.getMessage());
        }
    }
    
    @PutMapping("/addresses/{id}")
    @Transactional
    public ApiResponse<Void> updateAddress(@PathVariable Long id, @Valid @RequestBody AddressDto addressDto) {
        try {
            Long userId = userContextUtil.getCurrentUserId();
            Address address = addressRepository.findById(id)
                    .orElseThrow(() -> new RuntimeException("地址不存在"));
            
            // 检查地址是否属于当前用户
            if (!address.getUserId().equals(userId)) {
                throw new RuntimeException("无权操作此地址");
            }
            
            // 如果设置为默认地址，先取消其他默认地址
            if (addressDto.getIsDefault()) {
                addressRepository.clearDefaultAddresses(userId);
            }
            
            address.setName(addressDto.getName());
            address.setPhone(addressDto.getPhone());
            address.setDetail(addressDto.getDetail());
            address.setIsDefault(addressDto.getIsDefault());
            
            addressRepository.save(address);
            return ApiResponse.success("地址更新成功", null);
        } catch (Exception e) {
            return ApiResponse.error(e.getMessage());
        }
    }
    
    @DeleteMapping("/addresses/{id}")
    public ApiResponse<Void> deleteAddress(@PathVariable Long id) {
        try {
            Long userId = userContextUtil.getCurrentUserId();
            Address address = addressRepository.findById(id)
                    .orElseThrow(() -> new RuntimeException("地址不存在"));
            
            // 检查地址是否属于当前用户
            if (!address.getUserId().equals(userId)) {
                throw new RuntimeException("无权操作此地址");
            }
            
            addressRepository.delete(address);
            return ApiResponse.success("地址删除成功", null);
        } catch (Exception e) {
            return ApiResponse.error(e.getMessage());
        }
    }
    
    @PutMapping("/addresses/{id}/default")
    @Transactional
    public ApiResponse<Void> setDefaultAddress(@PathVariable Long id) {
        try {
            Long userId = userContextUtil.getCurrentUserId();
            Address address = addressRepository.findById(id)
                    .orElseThrow(() -> new RuntimeException("地址不存在"));
            
            // 检查地址是否属于当前用户
            if (!address.getUserId().equals(userId)) {
                throw new RuntimeException("无权操作此地址");
            }
            
            // 先取消所有默认地址
            addressRepository.clearDefaultAddresses(userId);
            
            // 设置当前地址为默认
            address.setIsDefault(true);
            addressRepository.save(address);
            
            return ApiResponse.success("默认地址设置成功", null);
        } catch (Exception e) {
            return ApiResponse.error(e.getMessage());
        }
    }
    
    @GetMapping("/addresses/default")
    public ApiResponse<AddressDto> getDefaultAddress() {
        try {
            Long userId = userContextUtil.getCurrentUserId();
            return addressRepository.findByUserIdAndIsDefaultTrue(userId)
                    .map(address -> ApiResponse.success(convertToDto(address)))
                    .orElse(ApiResponse.success(null));
        } catch (Exception e) {
            return ApiResponse.error(e.getMessage());
        }
    }
    
    private AddressDto convertToDto(Address address) {
        AddressDto dto = new AddressDto();
        dto.setId(address.getId());
        dto.setName(address.getName());
        dto.setPhone(address.getPhone());
        dto.setDetail(address.getDetail());
        dto.setIsDefault(address.getIsDefault());
        dto.setCreateTime(address.getCreateTime());
        return dto;
    }
}